/**
 * \file sem182.c
 *
 * \author      G. Leber
 * \author      H. Kantz
 *              Technische Universitaet Wien
 *              Institut fuer Technische Informatik E182/1
 *              Treitlstrasse 3
 *              1040 Wien
 *              Tel.: (0222) 58801 / 8168
 *              E-Mail: guenther@vmars.tuwien.ac.at
 * Update:      R. Kirner (use of semctl with enum semun)
 * \version     2.3
 * \date        3/5/02
 * Last Modified: $Author: bernd $
 */

/**< Generate the CVS-Id of this file just in case someone needs it. */
#define CVSID "$Id: sem182.c,v 1.2 2005/12/18 20:58:19 bernd Exp $"
#define sem182_c_sccsID "@(#)sem182.c	2.2	6/27/94"

#include "sem182.h"

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <errno.h>
#if __STDC__
#    include <stdlib.h>
#endif


#define SEM_NR 1


#if __STDC__
int semrm(const int semid)
#else
int semrm(semid) 
int semid;
#endif
{
    return semctl(semid, SEM_NR, IPC_RMID, 0);
}


#if __STDC__
int seminit(const key_t key, const int semperm, const int initval)
#else
int seminit(key, semperm, initval)
key_t key;
int semperm, initval;
#endif
{
#if !defined(__GNU_LIBRARY__) || defined(_SEM_SEMUN_UNDEFINED)
   union semun {
       int val;                    /* value for SETVAL */
       struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
       unsigned short int *array;  /* array for GETALL, SETALL */
   };
#endif

   int semid;
   union semun semarg;

   semarg.val = initval;
   semid = semget (key, SEM_NR, IPC_CREAT | IPC_EXCL | (semperm & 0666));
   if (semid == -1) {
       return -1;
   }
   /* Initialize Semaphore */
   if (semctl (semid, 0, SETVAL, semarg) == -1) {
       const int semctlerror = errno;	/* save error condition */

       (void) semrm(semid);
       errno = semctlerror;	/* restore error condition for user */
       return -1;
   }
   return semid;
}


#if __STDC__
int	semgrab(const key_t key)
#else
int	semgrab(key)
key_t key;
#endif
{
    return semget (key, SEM_NR, 0);
}

/* Dijkstra' s V(s) [signal] */
#if __STDC__
int	V(const int semid)
#else
int	V(semid)
int semid;
#endif
{  
    struct sembuf semp[1];

    semp[0].sem_num = 0;
    semp[0].sem_op = 1;
    semp[0].sem_flg = 0;
    return semop (semid, &semp[0], 1);
}


/* Dijkstra' s P(s) [wait] */
#if __STDC__
int	P(const int semid)
#else
int	P(semid)
int semid;
#endif
{
    struct sembuf semp[1];

    semp[0].sem_num = 0;
    semp[0].sem_op  = -1;
    semp[0].sem_flg = 0;
    return semop(semid, &semp[0], 1);
}

/*
 * Local Variables:
 * mode: c
 * c-indent-tabs-mode: nil
 * c-basic-offset: 4
 * End:
 */
